---
description: 如何維護更新日誌
title: 如何維護更新日誌
language: zh-TW
version: 0.3.0
---

:markdown
  # 如何維護更新日誌

  ## 更新日誌絕對不應該是 git 日誌的堆砌物

  Version **#{current_page.metadata[:page][:version]}**

  ### 更新日誌是什麽？
  更新日誌（Change Log）是一個由人工編輯，以時間為倒敘的列表。
  這個列表記錄所有版本的重大變動。


  <pre class="changelog">#{File.read("CHANGELOG.md")}</pre>

  ### 為何要提供更新日誌？
  為了讓用戶和開發人員更好知道每一個版本有哪些區別。

  ### 為何我要在乎呢？
  因為歸根結底軟體是為人提供的。既然你不關心人，那麽為何寫軟體呢？
  多少你還是要關心你的受眾。

  本文檔原作者和另外兩個人的一個[部落格][thechangelog]向大家介紹了，
  為何程式碼的管理者和開發者應該在乎更新日誌。如果你有一小時時間和很好的英文聽力本領，
  不妨聽聽。

  ### 怎麽定義好的更新日誌
  好問題！

  一個好的更新日誌，一定滿足：

  - 給人而不是機器寫的。記住，要說人話。
  - 快速跳轉到任意段。所以採用 markdown 格式
  - 一個版本對應一個章節。
  - 最新的版本在上面，最舊的在下面。
  - 所有日期採用 'YYYY-MM-DD' 這種規範。（例如北京奧運會的 2008 年 8 月 8 日是 2008-08-08）這個是國際通用，任何語言
  都能理解的，並且還被 [xkcd](https://xkcd.com/1179/) 推薦呢！
  - 標出來是否遵守[語義化版本格式][semver]
  - 每一個軟體的版本必須：
    - 標明日期（要用上面說過的規範）
    - 標明分類（採用英文）。規範如下：
      - 'Added' 添加的新功能
      - 'Changed' 功能變更
      - 'Deprecated' 不建議使用，未來會刪掉
      - 'Removed' 之前不建議使用的功能，這次真的刪掉了
      - 'Fixed' 修正的 bug
      - 'Security' 修正了安全相關的 bug


  ### 怎麽盡可能減少耗費的精力？
  永遠在文檔最上方提供一個 'Unreleased' 未發布區域，來記錄當前的變化。
  這樣做有兩大意義。

  - 大家可以看到接下來會有什麽變化
  - 在發布時，只要把 'Unreleased' 改為當前版本號，然後再添加一個新的 'Unreleased' 就行了


  ### 吐槽環節到了
  請你一定要注意：

  - **把 git 日誌扔到更新日誌裏。**看似有用，然而並沒有什麼作用。
  - **不寫 'deprecations' 就刪功能。**不帶這樣坑隊友的。
  - **採用各種不可靠的日期格式** 2012 年 12 月 12 日，也就懂中文的人能看得懂了。

  如果你還有要吐槽的，歡迎留 [issue][issues] 或者直接 PR


  ### 世界上不是有標準的更新日誌格式嗎？
  貌似 GNU 或者 GNU NEWS 還是提過些規範的，事實是它們太過簡陋了。
  開發有那麽多中情況，採用那樣的規範，確實是不太合適的。

  這個項目提供的[規範][CHANGELOG]是作者本人希望能夠成為世界規範的。
  作者不認為當前的標準足夠好，而且作為一個社區，我們是有能力提供更棒的規範。
  如果你對這個規範有不滿的地方，不要忘記還可以[吐槽][issues]呢。

  ### 更新日誌文件名應該叫什麽？

  我們的案例中給的名字就是最好的規範：`CHANGELOG.md`，注意大小寫。

  像 `HISTORY.txt`, `HISTORY.md`, `History.md`, `NEWS.txt`,
  `NEWS.md`, `News.txt`, `RELEASES.txt`, `RELEASE.md`, `releases.md` 這麽
  多文件名就太不統一了。

  只會讓大家更難找到。

  ### 為何不直接記錄 `git log`?

  因為 git 日誌一定是亂糟糟的。哪怕一個最理想的由完美的程序員開發的提交的，哪怕一個
  從不忘記每次提交全部文件，不寫錯別字，不忘記重構每一個部分——也無法保證 git 日誌完美無瑕。
  況且 git 日誌的核心在於記錄代碼的演化，而更新日誌則是記錄最重要的變更。

  就像註解之於程式碼，更新日誌之於 git 日誌。前者解釋*為什麽*，而後者說明*發生了什麽*。


  ### 更新日誌能機器識別嗎？
  非常困難，因為有各種不同的文件格式和其他規範。

  [Vandamme][vandamme] 是一支 Ruby 程式（由 [Gemnasium][gemnasium] 團隊制作），可以解析
  很多種（但絕對不是全部）開源程式庫的更新日誌。

  ### 到底是 CHANGELOG 還是更新日誌

  CHANGELOG 是文件名，更新日誌是常用說法。CHANGELOG 採用大寫是有歷史根源的。就像很多類似的文件
  [`README`][README]，[`LICENSE`][LICENSE]，還有 [`CONTRIBUTING`][CONTRIBUTING]。

  採用大寫可以更加顯著，畢竟這是項目很重要的 metadata。就像[開源徽章][shields]。

  ### 那些後來撤下的版本怎麽辦？
  因為各種安全/重大 bug 原因被撤下的版本被標記 'YANKED'。這些版本一般不出現在更新日誌裏，但作者建議他們出現。
  顯示方式應該是：

  `## [0.0.5] - 2014-12-13 [YANKED]`

  `[YANKED]` 採用大寫更加顯著，因為這個訊息很重要。而採用方括號則容易被程式解析。

  ### 是否可以重寫更新日誌
  當然。哪怕已經上線了，也可以重新更新更新日誌。有許多開源項目更新日誌不夠新，所以作者就會幫忙更新。

  另外，很有可能你忘記記錄一個重大功能更新。所以這時候應該去重寫更新日誌。

  ### 如何貢獻？
  本文檔並不是**真理**。這只是原作者的個人建議，並且包括許多收集的例子。
  哪怕[本開源庫][gh]提供一個[更新日誌案例][CHANGELOG]，我刻意沒有提供一個
  過於苛刻的規則列表（不像[語義化版本格式][semver]）。

  這是因為我希望通過社區達到統一觀點，我認為中間討論的過程與結果一樣重要。

  所以[歡迎貢獻][gh]。


  [CHANGELOG]: https://github.com/olivierlacan/keep-a-changelog/blob/master/CHANGELOG.md
  [CONTRIBUTING]: https://github.com/olivierlacan/keep-a-changelog/blob/master/CONTRIBUTING.md
  [LICENSE]: https://github.com/olivierlacan/keep-a-changelog/blob/master/LICENSE
  [README]: https://github.com/olivierlacan/keep-a-changelog/blob/master/README.md
  [gemnasium]: https://gemnasium.com/
  [gh]: https://github.com/olivierlacan/keep-a-changelog
  [issues]: https://github.com/olivierlacan/keep-a-changelog/issues
  [semver]: https://semver.org/lang/zh-CN/
  [shields]: https://shields.io/
  [thechangelog]: https://changelog.com/podcast/127
  [vandamme]: https://github.com/tech-angels/vandamme
